package com.example.demo.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.custom.AjaxResult;
import com.example.demo.custom.BaseController;
import com.example.demo.custom.TablePageable;
import com.example.demo.entity.Permission;
import com.example.demo.entity.SysRole;
import com.example.demo.form.SysRoleForm;
import com.example.demo.service.PermissionService;
import com.example.demo.service.SysRoleService;

@RestController
@RequestMapping(value = "/role")
public class SysRoleController extends BaseController<SysRole, Integer, SysRoleForm> {
	@Autowired
	private SysRoleService service;
	@Autowired
	private PermissionService permissionService;

	@RequestMapping(value = "/combotree")
	@ResponseBody
	public Object combotree(Integer id) {
		Sort sort = Sort.by("idx1");
		Specification<SysRole> spec = buildSpec1();
		List<SysRole> list = service.findAll(spec, sort);
		List<HashMap<String, Object>> result = buildTree(list, id);
		return new AjaxResult(result);
	}

	@RequestMapping(value = "/findAll")
	@ResponseBody
	public Object findAll() {
		List<SysRole> list = service.findAll();
		return new AjaxResult(list);
	}

	private List<HashMap<String, Object>> buildTree(List<SysRole> list, Integer id) {
		List<HashMap<String, Object>> result = new ArrayList<>();
		for (SysRole dept : list) {
			if (dept.getId() != id) {
				HashMap<String, Object> node = new HashMap<>();
				node.put("id", dept.getId());
				node.put("code", dept.getCode());
				node.put("name", dept.getName());
				node.put("idx1", dept.getIdx1());
				node.put("parentId", dept.getParentId());
				if (dept.getChildren().size() > 0) {
					node.put("nodes", buildTree(dept.getChildren(), id));
				}
				result.add(node);
			}
		}
		return result;
	}

	@SuppressWarnings("serial")
	private Specification<SysRole> buildSpec1() {
		Specification<SysRole> spec = new Specification<SysRole>() {
			@Override
			public Predicate toPredicate(Root<SysRole> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				return criteriaBuilder.isNull(root.get("parent"));
			}
		};
		return spec;
	}

	@SuppressWarnings("serial")
	@Override
	public Specification<SysRole> buildSpec(SysRoleForm form) {
		Specification<SysRole> spec = new Specification<SysRole>() {

			@Override
			public Predicate toPredicate(Root<SysRole> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules = new HashSet<>();
				rules.add(cb.isNull(root.get("parent")));
				String name = form.getName();
				if (StringUtils.hasText(name)) {
					rules.add(cb.like(root.get("name"), "%" + name + "%"));
				}
				String code = form.getCode();
				if (StringUtils.hasText(code)) {
					rules.add(cb.like(root.get("code"), "%" + code + "%"));
				}
				String search = form.getSearch();
				if (StringUtils.hasText(search)) {
					HashSet<Predicate> rules2 = new HashSet<>();
					rules2.add(cb.like(root.get("name"), "%" + search + "%"));
					rules2.add(cb.like(root.get("code"), "%" + search + "%"));
					rules.add(cb.or(rules2.toArray(new Predicate[rules2.size()])));
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return spec;
	}

	@Override
	public void edit(SysRoleForm form, ModelMap modelMap) throws InstantiationException, IllegalAccessException {
		SysRole model = new SysRole();
		Integer parentId = form.getParentId();
		if (parentId != null) {
			SysRole parent = service.findById(parentId);
			if (parent.getParent() == null) {
				model.setParent(parent);
			}
		}
		Integer id = form.getId();
		if (id != null) {
			model = service.findById(id);
		}
		modelMap.put("model", model);
	}

	@RequestMapping(value = "/save2")
	public Object save2(SysRoleForm form) {
		try {
			SysRole model = new SysRole();
			Integer id = form.getId();
			if (id != null) {
				model = service.findById(id);
			}
			Integer parentId = form.getParentId();
			if (parentId != null) {
				model.setParent(service.findById(parentId));
			} else {
				model.setParent(null);
			}
			String pCode = form.getPermissionCode();
			if (StringUtils.hasText(pCode)) {
				Permission permission = permissionService.findByCode(pCode);
				model.setName(permission.getName());
				model.setCode(permission.getCode());
			} else {
				model.setName(form.getName());
				model.setCode(form.getCode());
			}
			model.setIdx1(form.getIdx1());
			service.save(model);
			return new AjaxResult("数据保存成功");
		} catch (Exception e) {
			return new AjaxResult(false, "数据保存失败");
		}
	}

}
